package main

import (
	"fmt"
	"log"
	"math/rand"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"thumbor-proxy/httpproxy"
	"time"
)

/**
 * @type 设置handle数据结构
 */
type handle struct {
	host string
	port string
}

var domainAddress = "http://old.brc-ulife.com:8899"
var innerIP = "http://172.18.140.237:10000"

var domainAddress_ = "https://fileview.brc-ulife.com"
var innerIP_ = "http://172.18.140.235:8000"

/**
 * @func 三目运算函数
 */
func If(condition bool, trueVal interface{}, falseVal interface{}) interface{} {
	if condition {
		return trueVal
	}
	return falseVal
}

/**
 * @func 处理HTTP请求函数
 */
func (this *handle) ServeHTTP(w http.ResponseWriter, r *http.Request) {

	//后端端口范围
	a := [30]string{"8000", "8001", "8002", "8003", "8004", "8005", "8006", "8007", "8008", "8009", "8022", "8023", "8024", "8025", "8026", "8027", "8028", "8029", "8030", "8031", "8032", "8033", "8034", "8035", "8036", "8037", "8038", "8039", "8040", "8041"}
	i := rand.Intn(30)
	serverPort := a[i]
	//log.Println(" index : ", i, " port : ", serverPort)

	//设置后端的反向代理服务器URL
	remote, err := url.Parse("http://" + this.host + ":" + serverPort)

	//URL解析错误，则打印错误信息
	if err != nil {
		log.Println(" url parse error : ", err)
	}

	//URL后缀标识
	flag := If(strings.Contains(r.RequestURI, "?"), "&", "?").(string)

	//设置URL前缀
	r.RequestURI = strings.Replace(r.RequestURI, domainAddress, innerIP, -1)
	r.RequestURI = strings.Replace(r.RequestURI, domainAddress_, innerIP_, -1)

	//设置新的URL
	r.RequestURI = r.RequestURI + flag + "tempstamp=" + fmt.Sprintf("%d", time.Now().Unix())

	//打印URL地址信息
	if !strings.Contains(r.RequestURI, "www.baidu.com") {
		log.Println(" request url ", r.Host+r.RequestURI, " remote url : ", remote.String()+r.RequestURI)
	}

	//设置代理服务
	proxy := httpproxy.NewSingleHostReverseProxy(remote)

	//处理HTTP请求
	proxy.ServeHTTP(w, r)

	log.Println(" serve http request over ... ")
}

/**
 * @func 启动代理服务器
 */
func startServer() {

	//设置随机数种子
	rand.Seed(time.Now().Unix())

	//后端端口范围
	a := [10]string{"9000", "9000", "9000", "9000", "9000", "9000", "9000", "9000", "9000", "9000"}
	i := rand.Intn(10)
	serverPort := a[i]
	log.Println(" index : ", i, " port : ", serverPort)

	//监听端口
	listenPorts, errs := strconv.Atoi(serverPort)
	if errs != nil {
		log.Println(" string transfer to int error : ", errs)
	}
	log.Println(" listen port : ", listenPorts)

	//被代理的服务器host和port
	h := &handle{host: "localhost", port: serverPort}

	//启动服务并监听端口
	err := http.ListenAndServe(":"+strconv.Itoa(listenPorts), h)

	//如果发生错误，打印错误日志并退出
	if err != nil {
		log.Fatalln("ListenAndServe: ", err)
	}
}

/**
 * @func 启动服务
 */
func starting() {

	/**
	 * @func recover恢复函数
	 */
	defer func() {
		if info := recover(); info != nil {
			log.Println(" program system error : ", info)
		} else {
			log.Println(" program over ... ")
		}
	}()

	log.Println("start server ... ")

	//开始启动服务
	startServer()

	log.Println("start server exit ... ")
}

/**
 * @func 主函数
 */
func main() {
	//启动服务，提供反向代理业务
	starting()
}
